// this file is used by http handlers. no need to refactor when not adding new features.

package session

import (
	"fmt"
	"net/http"
	"net/url"
	"strings"

	"codeberg.org/vnpower/pixivfe/v2/config"
)

// GetUserToken retrieves the authentication token for the Pixiv API from the 'pixivfe-Token' cookie.
// This token takes precedence over the default one provided by tokenManager.
func GetUserToken(r *http.Request) string {
	return GetCookie(r, Cookie_Token)
}

func GetImageProxy(r *http.Request) url.URL {
	value := GetCookie(r, Cookie_ImageProxy)
	if value == "" {
		// fall through to default case
	} else {
		// NOTE: do not use urlx for parsing here, a URI path like /proxy/i.pximg.net will fail to parse
		// This will cause the default ProxyServer be silently used instead despite a UI change on the Settings page
		proxyUrl, err := url.Parse(value)
		if err != nil {
			// fall through to default case
		} else {
			return *proxyUrl
		}
	}
	return config.GlobalConfig.ProxyServer
}

func ProxyImageUrl(r *http.Request, s string) (string, error) {
	proxyOrigin, err := GetImageProxyPrefix(r)
	if err != nil {
		return "", err
	}
	s = strings.ReplaceAll(s, `https:\/\/i.pximg.net`, proxyOrigin)
	// s = strings.ReplaceAll(s, `https:\/\/i.pximg.net`, "/proxy/i.pximg.net")
	s = strings.ReplaceAll(s, `https:\/\/s.pximg.net`, "/proxy/s.pximg.net")
	return s, nil
}

func ProxyImageUrlNoEscape(r *http.Request, s string) (string, error) {
	proxyOrigin, err := GetImageProxyPrefix(r)
	if err != nil {
		return "", err
	}
	s = strings.ReplaceAll(s, `https://i.pximg.net`, proxyOrigin)
	// s = strings.ReplaceAll(s, `https:\/\/i.pximg.net`, "/proxy/i.pximg.net")
	s = strings.ReplaceAll(s, `https://s.pximg.net`, "/proxy/s.pximg.net")
	return s, nil
}

func GetImageProxyOrigin(r *http.Request) (string, error) {
	proxyURL := GetImageProxy(r)
	authority, err := urlAuthority(proxyURL)
	if err != nil {
		return "", err
	}
	return authority, nil
}

func GetImageProxyPrefix(r *http.Request) (string, error) {
	proxyURL := GetImageProxy(r)
	authority, err := urlAuthority(proxyURL)
	if err != nil {
		return "", err
	}
	return authority + proxyURL.Path, nil
	// iacore: not sure if url.EscapedPath() is useful here. go's standard library is trash at handling URL (:// should be part of the scheme)
}

// urlAuthority returns the authority part of a URL, ensuring that both scheme and host are present or neither.
//
// Returns an error if the URL has only scheme or only host.
//
// iacore: still cannot believe Go doesn't have this function built-in. if stability is their goal, they really don't have the incentive to add useful, crucial features
func urlAuthority(u url.URL) (string, error) {
	if (u.Scheme != "") != (u.Host != "") {
		return "", fmt.Errorf("url must have both scheme and authority or neither: %s", u.String())
	}

	authority := ""
	if u.Scheme != "" {
		authority += u.Scheme + "://"
	}
	authority += u.Host

	return authority, nil
}
